package presentation;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingConstants;

import service.MonopolyService;
import core.Item;
/**
 * A fő ablak osztyálya.
 * Ez szolgál a játék teljes egészében való megjelenítésére.
 * 
 * @author Szabolcs
 *
 */
@SuppressWarnings("serial")
public class MainFrame extends JFrame {
	ShowItem[] showItems = new ShowItem[41];

	/**
	 * A játék irányító aobiektuma.
	 */
	private MonopolyService mService;
	
	/**
	 * A menüszerkezet.
	 */
	private JMenuBar menuBar;
	private JMenu game;
	private JMenu options;
	private JMenu help;
	private JMenuItem newGame;
	private JMenuItem loadGame;
	private JMenuItem saveGame;
	private JMenuItem playerOptions;
	private JMenuItem about;
	private JMenuItem helpp;
	private JPanel startPanel;

	private JButton throwButton;
	private JButton buyButton;
	private JButton nextPlayerButton;
	private JLabel priceLabel;
	private JLabel playerLabel;

	/**
	 * Specifikus megjelenítési változók.
	 */
	int x0 = 100;
	int y0 = 10;
	int width = 70;
	int height = 50;
	int space = 3;

	int position = 0;

	private class NewGameActionListener implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			newGame();
			repaint();
		}
	}

	private class OptionsActionListener implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			options();
		}
	}

	private class ItemMouseListener extends MouseAdapter {
		public void mouseClicked(MouseEvent e) {
			System.out.println(((ShowItem) e.getSource()).getName() + " klikk!");
		}
	}

	private class NextPlayerActionListener implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			mService.unpaintItems();
			showItems[position].deselect();
			nextPlayerButton.setText(mService.nextPlayer());
			nextPlayerButton.setEnabled(false);
			throwButton.setEnabled(true);
			buyButton.setEnabled(false);
			mService.paintItems();
			setMoney();
		}
	}

	private class BuyActionListener implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			buySelected();
			buyButton.setEnabled(false);
			mService.paintItems();
			setMoney();
		}
	}

	private class ThrowActionListener implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			showItems[position].deselect();
			int num = mService.throwDice();
			if (num < 0) {
				mService.step(-num);
				doubleThrow(-num);
			} else {
				setPosition(mService.step(num));
				simpleThrow(num);
				throwButton.setEnabled(false);
				buyButton.setEnabled(true);
				nextPlayerButton.setEnabled(true);
			}
		}
	}

	/**
	 * Elvégzi az inicializálásokat.
	 * Felépi az ablakot és a menüket.
	 * @param ms az irányító obiektum
	 */
	public MainFrame(MonopolyService ms) {
		mService = ms;
		menuBar = new JMenuBar();
		game = new JMenu("Játék");
		options = new JMenu("Beállítások");
		help = new JMenu("Súgó");
		newGame = new JMenuItem("Új játék");
		loadGame = new JMenuItem("Játék betöltése");
		saveGame = new JMenuItem("Játék mentése");
		playerOptions = new JMenuItem("Játékos beállítások");
		about = new JMenuItem("Névjegy");
		helpp = new JMenuItem("Segítség");
		game.add(newGame);
		game.add(loadGame);
		game.add(saveGame);
		// game.add(exit);
		options.add(playerOptions);
		help.add(about);
		help.add(helpp);
		menuBar.add(game);
		menuBar.add(options);
		// menuBar.add(help);

		startPanel = new JPanel();
		startPanel.setLayout(new BorderLayout());
		JLabel tempLabel = new JLabel("M O N O P O L Y");
		tempLabel.setFont(new Font("Arial", Font.BOLD, 80));
		tempLabel.setHorizontalAlignment(SwingConstants.CENTER);
		tempLabel.setForeground(Color.WHITE);
		startPanel.add(tempLabel);
		startPanel.setBackground(new Color(0, 100, 0));
		this.setContentPane(startPanel);

		newGame.addActionListener(new NewGameActionListener());
		playerOptions.addActionListener(new OptionsActionListener());

		this.setTitle("Monopoly");
		this.setJMenuBar(menuBar);
		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
	}

	/**
	 * Új játék kezdéséhez szükséges műveleteket végzi el.
	 */
	private void newGame() {
		options();

		Item[] items = mService.getItems();

		for (int i = 0; i < 10; ++i) {
			showItems[i] = new ShowItem(items[i],
					mService.getGroupColor(items[i].getGroup()));
			startPanel.add(showItems[i]);
			showItems[i].setBounds((10 - i) * (width + space) + x0, 10
					* (height + space) + y0, width, height);
			showItems[i].addMouseListener(new ItemMouseListener());
		}
		for (int i = 10; i < 20; ++i) {
			showItems[i] = new ShowItem(items[i],
					mService.getGroupColor(items[i].getGroup()));
			startPanel.add(showItems[i]);
			showItems[i].setBounds(x0, (20 - i) * (height + space) + y0, width,
					height);
			showItems[i].addMouseListener(new ItemMouseListener());
		}
		for (int i = 20; i < 30; ++i) {
			showItems[i] = new ShowItem(items[i],
					mService.getGroupColor(items[i].getGroup()));
			startPanel.add(showItems[i]);
			showItems[i].setBounds((i - 20) * (width + space) + x0, y0, width,
					height);
			showItems[i].addMouseListener(new ItemMouseListener());
		}
		for (int i = 30; i < 40; ++i) {
			showItems[i] = new ShowItem(items[i],
					mService.getGroupColor(items[i].getGroup()));
			startPanel.add(showItems[i]);
			showItems[i].setBounds(10 * (width + space) + x0, (i - 30)
					* (height + space) + y0, width, height);
			showItems[i].addMouseListener(new ItemMouseListener());
		}
		showItems[40] = new ShowItem(items[10],
				mService.getGroupColor(items[10].getGroup()));
		startPanel.add(showItems[40]);
		showItems[40].setBounds(10 * (width + space) + x0, (9)
				* (height + space) + y0, width, height);

		startPanel.remove(showItems[40]);
		this.setBackground(getBackground());
		this.setVisible(false);
		this.setVisible(true);

		throwButton = new JButton("Dobás");
		startPanel.add(throwButton);
		throwButton.setBounds(180, 160, 120, 60);
		throwButton.addActionListener(new ThrowActionListener());

		buyButton = new JButton("Vásárlás");
		startPanel.add(buyButton);
		buyButton.setBounds(310, 160, 120, 60);
		buyButton.addActionListener(new BuyActionListener());

		nextPlayerButton = new JButton("Indít!");
		startPanel.add(nextPlayerButton);
		nextPlayerButton.setBounds(650, 470, 150, 60);
		nextPlayerButton.addActionListener(new NextPlayerActionListener());

		buyButton.setEnabled(false);
		throwButton.setEnabled(false);

		priceLabel = new JLabel();
		startPanel.add(priceLabel);
		priceLabel.setBounds(440, 160, 120, 60);

		playerLabel = new JLabel("Player");
		startPanel.add(playerLabel);
		playerLabel.setBounds(50, 50, 50, 50);

		startPanel.remove(playerLabel);
		mService.setShowItems(showItems);
	}

	/**
	 * A beállítások ablak megjelenítése.
	 */
	private void options() {
		this.setEnabled(false);
		OptionsFrame of = new OptionsFrame(this);
		of.setVisible(true);
		of.setBounds(150, 150, 250, 200);
		of.setResizable(false);
	}

	/**
	 * A játékosok beállítsa
	 * @param nr a játékosok száma
	 * @param n1 1. játékos neve
	 * @param n2 2. játékos neve
	 * @param n3 3. játékos neve
	 * @param n4 4. játékos neve
	 */
	public void setPlayers(int nr, String n1, String n2, String n3, String n4) {
		mService.setPlayerNames(nr, n1, n2, n3, n4);
	}

	/**
	 * A aktuális játékos táblán elfoglalt helyének beállítása.
	 * @param pos a hely
	 */
	public void setPosition(int pos) {
		position = pos;
		showItems[position].select();
	}

	/**
	 * Értesítést küld, ha duplát dobtunk.
	 * @param num a dobott szám
	 */
	private void doubleThrow(int num) {
		JOptionPane.showMessageDialog(this, Integer.toString(num)
				+ ": Duplát dobtál, dobj még egyszer!");
	}

	/**
	 * Értesít, hogy hányast dobtunk.
	 * @param num a dobás értéke
	 */
	private void simpleThrow(int num) {
		JOptionPane.showMessageDialog(this, Integer.toString(num)
				+ "-t dobtál.");
	}

	/**
	 * A kiválasztottak vásárlása.
	 */
	private void buySelected() {
		mService.buyFromBank(showItems[position].getItem());
	}

	/**
	 * Játékos pénzének beállítása.
	 */
	private void setMoney() {
		priceLabel.setText(Integer.toString(mService.getMoney()));
	}
}
